import { forwardRef, useEffect, useImperativeHandle } from "react";
import { Button, Form, Input, Radio, Select } from "antd";
import styles from "./index.module.less";
import { isEmptyType } from "@/utils/types";
import { addKey } from "@/utils/tools";

const FormItems: any = {
  input: (props: any) => <Input {...props} />,
  inputPassword: (props: any) => <Input.Password {...props} />,
  select: (props: any) => {
    const { width = "100%", ...args } = props;
    const $props = {
      style: { width },
      ...args,
    };
    return <Select {...$props} />;
  },
  radio: (props: any) => {
    const { options, ...args } = props;
    return (
      <Radio.Group {...args}>
        {addKey(options).map(({ label, value, diff_key }: any) => (
          <Radio value={value} key={diff_key}>
            {label}
          </Radio>
        ))}
      </Radio.Group>
    );
  },
};

const handleSubmit = ({ queryForm, refreshData }: any) => {
  return () => refreshData && refreshData(queryForm.getFieldsValue());
};
const handleResetForm = ({ queryForm, refreshData }: any) => {
  return () => {
    queryForm.resetFields();
    refreshData && refreshData(queryForm.getFieldsValue());
  };
};

const renderFormSubmit = (props: any) => {
  const { okText, cancelText, ...args } = props;
  return (
    <Form.Item>
      <div className={styles.submit}>
        <Button type="primary" onClick={handleSubmit(args)}>
          {okText}
        </Button>
        <Button onClick={handleResetForm(args)}>{cancelText}</Button>
      </div>
    </Form.Item>
  );
};

const BasicForm = (props: any, ref: any) => {
  const {
    formList,
    requiredFields = [],
    setDisabled,
    refreshData,
    renderExra,
    okText = "查询",
    cancelText = "重置",
    formItemLayout = null,
    layout = "inline",
    isShowSubmit = true,
    isInlineLayout = true,
    columnCount,
  } = props;
  const renderFormItems = (formList: any) => {
    return addKey(formList).map((item: any) => {
      let { type, name, label, rules, diff_key, formItemStyle, ...args } = item;
      if (columnCount) {
        formItemStyle = {
          width: `calc(100% / ${columnCount})`,
          marginInlineEnd: "0",
        };
      }
      const FORM_ITEM = FormItems[type](args);
      return (
        <Form.Item
          key={diff_key}
          name={name}
          label={label}
          rules={rules}
          style={formItemStyle}
        >
          {FORM_ITEM}
        </Form.Item>
      );
    });
  };
  const [queryForm] = Form.useForm();
  const FormListDOM = (
    <Form
      {...formItemLayout}
      layout={layout}
      form={queryForm}
      className={isInlineLayout && styles.formInline}
    >
      {renderFormItems(formList)}
      {isShowSubmit &&
        renderFormSubmit({ queryForm, refreshData, okText, cancelText })}
    </Form>
  );

  const getFieldsValue = () => queryForm.getFieldsValue();
  const setFieldsValue = (object: any) => queryForm.setFieldsValue(object);
  const validateFields = () => queryForm.validateFields();
  const resetFields = () => queryForm.resetFields();

  useImperativeHandle(ref, () => ({
    getFieldsValue,
    setFieldsValue,
    validateFields,
    resetFields,
    handleResetForm: handleResetForm({ queryForm }),
    queryForm,
  }));

  const listenFields = requiredFields.map((key: any) =>
    Form.useWatch(key, queryForm)
  );

  useEffect(() => {
    const boolean = listenFields.some((value: any) => isEmptyType(value));
    setDisabled && setDisabled(boolean);
  }, listenFields);

  return isShowSubmit ? (
    <div className={styles["basic-form"]}>
      <div className={styles.form}>{FormListDOM}</div>
      <div className={styles.extra}>{renderExra && renderExra()}</div>
    </div>
  ) : (
    FormListDOM
  );
};
export default forwardRef(BasicForm);
